package com.dd.edu.guava.service;

import com.alibaba.fastjson.JSONObject;
import com.dd.edu.guava.dao.HotBeanDao;
import com.dd.edu.guava.entity.HotBean;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.JedisPoolConfig;

import javax.annotation.PostConstruct;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
public class HotBeanService {

    @Autowired
    private HotBeanDao hotBeanDao;

    private Cache<Object, Object> hotCache;
    private JedisCluster jedisCluster;

    @PostConstruct
    private void init(){

        // 初始化redisCluster
        JedisPoolConfig config = new JedisPoolConfig();
        Set<HostAndPort> jedisClusterNode = new HashSet<>();
        jedisClusterNode.add(new HostAndPort("192.168.1.202", 7001));
        jedisClusterNode.add(new HostAndPort("192.168.1.202", 7002));
        jedisClusterNode.add(new HostAndPort("192.168.1.202", 7003));
        jedisClusterNode.add(new HostAndPort("192.168.1.202", 7004));
        jedisClusterNode.add(new HostAndPort("192.168.1.202", 7005));
        jedisClusterNode.add(new HostAndPort("192.168.1.202", 7006));
        jedisCluster = new JedisCluster(jedisClusterNode, config);

        // 初始化guavaCache
        hotCache = CacheBuilder.newBuilder().recordStats().maximumSize(1000)
                .expireAfterAccess(10, TimeUnit.SECONDS)
                .build();
//                .build(new CacheLoader<Integer, HotBean>() {
//                    @Override
//                    public HotBean load(Integer id) {
//                        // 2
//                        return getHotBeanByIdOfRedis(id);
//                    }
//                });
    }
    // 3
    public HotBean getHotBeanByIdOfRedis(Integer id) {
        if (id == null) {
            throw new RuntimeException("id is null");
        }

        log.info("guava中未获取到，开始从redis分布式缓存中获取");
        String json = jedisCluster.get(String.valueOf(id));
        if(json != null && !"".equals(json)){
            log.info("从redis分布式缓存中获取数据：成功");
            return JSONObject.parseObject(json, HotBean.class);
        } else {
            log.info("从redis分布式缓存中获取数据：失败");
            HotBean hotBean = hotBeanDao.findById(id).orElse(null);
            if(hotBean != null) {
                log.info("从DB中获取数据：成功");
                jedisCluster.set(String.valueOf(id), JSONObject.toJSONString(hotBean));
                // 4
                return hotBean;
            }
            log.info("从DB中获取数据：失败");
        }

        return null;
    }

    // 1
    public HotBean getHotBeanById(Integer id) throws ExecutionException {
        if (id == null) {
            throw new RuntimeException("id is null");
        }
        log.info("开始从guava中获取数据");
        // 从guava cache中获取数据，不存在则到redis中获取，redis没有上db获取
        return (HotBean) hotCache.get(id, () -> {
            HotBean hotBean = getHotBeanByIdOfRedis(id);
            if (hotBean != null){
                hotCache.put(id, hotBean);
            }
            return hotBean;
        });
    }

}
